home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / set.h < prev    next >
C/C++ Source or Header  |  1999-05-14  |  15KB  |  613 lines

  1. // $Id: set.h,v 1.3 1999/01/25 20:00:31 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef set_INCLUDED
  11. #define set_INCLUDED
  12.  
  13. #include "config.h"
  14. #include "assert.h"
  15. #include "symbol.h"
  16.  
  17. class ShadowSymbol
  18. public:
  19.     ShadowSymbol *next;
  20.     Symbol *symbol;
  21.     int pool_index;
  22.  
  23.     inline NameSymbol *Identity() { return symbol -> Identity(); }
  24.  
  25.     ShadowSymbol(Symbol *symbol_) : symbol(symbol_),
  26.                                     conflict(NULL)
  27.     {}
  28.  
  29.     ~ShadowSymbol() { delete conflict; }
  30.  
  31.     Symbol *Conflict(int i) { return (*conflict)[i]; }
  32.  
  33.     inline int NumConflicts()
  34.     {
  35.         return (conflict ? conflict -> Length() : 0);
  36.     }
  37.  
  38.     inline void AddConflict(Symbol *conflict_symbol)
  39.     {
  40.         if ((symbol != conflict_symbol) && (! Find(conflict_symbol)))
  41.             conflict -> Next() = conflict_symbol;
  42.         return;
  43.     }    
  44.  
  45.     inline void RemoveConflict(int k)
  46.     {
  47.         int last_index = conflict -> Length() - 1;
  48.         if (k < 0) // when k is negative, it identifies the main symbol
  49.              symbol = (*conflict)[last_index];
  50.         else (*conflict)[k] = (*conflict)[last_index];
  51.         conflict -> Reset(last_index);
  52.     }
  53.  
  54. private:
  55.     Tuple<Symbol *> *conflict;
  56.  
  57.     bool Find(Symbol *conflict_symbol)
  58.     {
  59.         if (! conflict)
  60.             conflict = new Tuple<Symbol *>(4);
  61.         for (int k = 0; k < conflict -> Length(); k++)
  62.             if ((*conflict)[k] == conflict_symbol)
  63.                 return true;
  64.         return false;
  65.     }    
  66. };
  67.  
  68.  
  69. class SymbolSet
  70. {
  71. public:
  72.     enum
  73.     {
  74.         DEFAULT_HASH_SIZE = 13,
  75.         MAX_HASH_SIZE = 1021
  76.     };
  77.  
  78.     SymbolSet(int hash_size_ = DEFAULT_HASH_SIZE) : symbol_pool(256),
  79.                                                     main_index(0),
  80.                                                     sub_index(0)
  81.     {
  82.         hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  83.  
  84.         prime_index = -1;
  85.         do
  86.         {
  87.             if (hash_size < primes[prime_index + 1])
  88.                 break;
  89.             prime_index++;
  90.         } while (primes[prime_index] < MAX_HASH_SIZE);
  91.  
  92.         base = (ShadowSymbol **) memset(new ShadowSymbol *[hash_size], 0, hash_size * sizeof(ShadowSymbol *));
  93.     }
  94.  
  95.     ~SymbolSet();
  96.  
  97.     //
  98.     // Calculate the size of the set an return the value.
  99.     //
  100.     inline int Size()
  101.     {
  102.         int size = 0;
  103.  
  104.         for (int i = 0; i < symbol_pool.Length(); i++)
  105.         {
  106.             ShadowSymbol *shadow = symbol_pool[i];
  107.             Symbol *symbol = shadow -> symbol;
  108.             for (int k = 0; symbol; symbol = (Symbol *) (k < shadow -> NumConflicts() ? shadow -> Conflict(k++) : NULL))
  109.                 size++;
  110.         }
  111.  
  112.         return size;
  113.     }
  114.  
  115.     //
  116.     // Empty out the set in question - i.e., remove all its elements
  117.     //
  118.     inline void SetEmpty()
  119.     {
  120.         for (int i = 0; i < symbol_pool.Length(); i++)
  121.             delete symbol_pool[i];
  122.         symbol_pool.Reset();
  123.         base = (ShadowSymbol **) memset(base, 0, hash_size * sizeof(ShadowSymbol *));
  124.     }
  125.  
  126.     //
  127.     // Empty out the set in question - i.e., remove all its elements
  128.     //
  129.     bool IsEmpty() { return symbol_pool.Length() == 0; }
  130.  
  131.     //
  132.     // Assignment of a set to another.
  133.     //
  134.     SymbolSet &operator=(SymbolSet &rhs)
  135.     {
  136.         if (this != &rhs)
  137.         {
  138.             this -> SetEmpty();
  139.             this -> Union(rhs);
  140.         }
  141.  
  142.         return *this;
  143.     }
  144.  
  145.     //
  146.     // Equality comparison of two sets
  147.     //
  148.     bool operator==(SymbolSet &);
  149.  
  150.     //
  151.     // NonEquality comparison of two sets
  152.     //
  153.     inline bool operator!=(SymbolSet &rhs)
  154.     {
  155.         return ! (*this == rhs);
  156.     }
  157.  
  158.     //
  159.     // Union the set in question with the set passed as argument: "set"
  160.     //
  161.     void Union(SymbolSet &);
  162.  
  163.     //
  164.     // Intersect the set in question with the set passed as argument: "set"
  165.     //
  166.     void Intersection(SymbolSet &);
  167.  
  168.     //
  169.     // Return a bolean value indicating whether or not the set in question intersects the set passed as argument: "set"
  170.     // i.e., is there at least one element of set that is also an element of "this" set.
  171.     //
  172.     bool Intersects(SymbolSet &);
  173.  
  174.     //
  175.     // How many elements with this name symbol do we have?
  176.     //
  177.     inline int NameCount(Symbol *element)
  178.     {
  179.         NameSymbol *name_symbol = element -> Identity();
  180.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  181.         {
  182.             if (shadow -> Identity() == name_symbol)
  183.                 return shadow -> NumConflicts() + 1;
  184.         }
  185.  
  186.         return 0;
  187.     }
  188.  
  189.     //
  190.     // Is "element" an element of the set in question ?
  191.     //
  192.     inline bool IsElement(Symbol *element)
  193.     {
  194. assert(element);
  195.         NameSymbol *name_symbol = element -> Identity();
  196.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  197.         {
  198.             if (shadow -> Identity() == name_symbol)
  199.             {
  200.                 Symbol *symbol = shadow -> symbol;
  201.                 for (int k = 0; symbol; symbol = (Symbol *) (k < shadow -> NumConflicts() ? shadow -> Conflict(k++) : NULL))
  202.                 {
  203.                     if (symbol == element)
  204.                         return true;
  205.                 }
  206.  
  207.                 return false;
  208.             }
  209.         }
  210.  
  211.         return false;
  212.     }
  213.  
  214.     //
  215.     // Add element to the set in question if was not already there.
  216.     //
  217.     inline void AddElement(Symbol *element)
  218.     {
  219.         NameSymbol *name_symbol = element -> Identity();
  220.         int i = name_symbol -> index % hash_size;
  221.  
  222.         ShadowSymbol *shadow;
  223.         for (shadow = base[i]; shadow; shadow = shadow -> next)
  224.         {
  225.             if (shadow -> Identity() == name_symbol)
  226.             {
  227.                 shadow -> AddConflict(element);
  228.                 return;
  229.             }
  230.         }
  231.  
  232.         shadow = new ShadowSymbol(element);
  233.         shadow -> pool_index = symbol_pool.Length();
  234.         symbol_pool.Next() = shadow;
  235.  
  236.         shadow -> next = base[i];
  237.         base[i] = shadow;
  238.  
  239.         //
  240.         // If the set is "adjustable" and the number of unique elements in it exceeds
  241.         // 2 times the size of the base, and we have not yet reached the maximum
  242.         // allowable size for a base, reallocate a larger base and rehash the elements.
  243.         //
  244.         if ((hash_size < MAX_HASH_SIZE) && (symbol_pool.Length() > (hash_size << 1)))
  245.             Rehash();
  246.  
  247.         return;
  248.     }
  249.  
  250.  
  251.     void RemoveElement(Symbol *);
  252.  
  253.     Symbol* FirstElement()
  254.     {
  255.         main_index = 0;
  256.         sub_index = 0;
  257.         return (main_index < symbol_pool.Length() ? symbol_pool[main_index] -> symbol : (Symbol *) NULL);
  258.     }
  259.  
  260.     Symbol* NextElement()
  261.     {
  262.         Symbol *symbol = NULL;
  263.  
  264.         if (main_index < symbol_pool.Length())
  265.         {
  266.              if (sub_index < symbol_pool[main_index] -> NumConflicts())
  267.                   symbol = symbol_pool[main_index] -> Conflict(sub_index++);
  268.              else
  269.              {
  270.                  main_index++;
  271.                  sub_index = 0;
  272.                  symbol = (main_index < symbol_pool.Length() ? symbol_pool[main_index] -> symbol : (Symbol *) NULL);
  273.              }
  274.         }
  275.  
  276.         return symbol;
  277.     }
  278.  
  279. protected:
  280.  
  281.     Tuple<ShadowSymbol *> symbol_pool;
  282.  
  283.     int main_index,
  284.         sub_index;
  285.  
  286.     ShadowSymbol **base;
  287.     int hash_size;
  288.  
  289.     static int primes[];
  290.     int prime_index;
  291.  
  292.     void Rehash();
  293. };
  294.  
  295.  
  296. //
  297. // Single-value Mapping from a name_symbol into a symbol with that name.
  298. //
  299. class SymbolMap : public SymbolSet
  300. {
  301. public:
  302.     SymbolMap(int hash_size_ = DEFAULT_HASH_SIZE) : SymbolSet(hash_size_)
  303.     {}
  304.  
  305.     //
  306.     // Is there an element with this name in the map ?
  307.     //
  308.     inline Symbol *Image(NameSymbol *name_symbol)
  309.     {
  310. assert(name_symbol);
  311.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> n